package interpreter

import (
	"kumachan/standalone/util/fatal"
	"kumachan/interpreter/runtime/vm"
	"kumachan/interpreter/runtime/rt"
	"kumachan/interpreter/compiler/loader"
	"kumachan/interpreter/compiler/checker"
	"kumachan/interpreter/compiler/generator"
)

type Program struct {
	EntryModule      *loader.Module
	ModuleIndex      loader.Index
	CheckedProgram   *checker.Program
	CompiledProgram  *rt.Program
}
func Compile(entry_path string) (*Program, fatal.Exception) {
	// load source files
	var entry, idx, err1 = loader.LoadEntryAllowEmpty(entry_path)
	if err1 != nil { return nil, err1 }
	// type check
	var raw_program, err2 = checker.TypeCheck(entry)
	if err2 != nil { return nil, err2 }
	// generate bytecode
	var program, err3 = generator.Compile(raw_program)
	if err3 != nil { return nil, err3 }
	// produce compiled program
	return &Program {
		EntryModule:     entry,
		ModuleIndex:     idx,
		CheckedProgram:  raw_program,
		CompiledProgram: program,
	}, nil
}
func Run(p *Program,  options *vm.Options) {
	vm.Execute(p.CompiledProgram, options)
}


